package com.lzkjiot.service.gnss.transger.core.transfer;

import com.lzkjiot.service.gnss.transger.core.DataInFrame;
import com.lzkjiot.service.gnss.transger.core.transfer.CacheData;
import com.lzkjiot.service.gnss.transger.core.transfer.condition.ConditionCacheManager;
import com.lzkjiot.service.gnss.transger.core.transfer.condition.GnssConditionTransferWorker;
import com.lzkjiot.service.gnss.transger.core.transfer.gnssdata.GnssDataCacheManager;
import com.lzkjiot.service.gnss.transger.core.transfer.gnssdata.GnssRTCMDataTransferWorker;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class GnssDataTransfer {

    @Autowired
    GnssDataCacheManager gnssDataCacheManager;

    @Autowired
    ConditionCacheManager conditionCacheManager;

    @Autowired
    GnssConditionTransferWorker gnssConditionTransferWorker;

    private final ExecutorService execWorkerPool = Executors.newFixedThreadPool(4);

    @PostConstruct
    public void init() {
        log.info("############### Start GNSS TransferWorker... ###############");
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        CacheData data = gnssDataCacheManager.get();
                        if(data != null){
                            int deviceId = data.getDeviceId();
                            byte[] frameData = data.getData();
//                            log.warn("[GnssDataTransfer] Current deviceId:{}, data len:{}", deviceId, frameData.length);
                            // 检查数据帧长度是否合法
                            if (frameData.length > 6) {
                                //端口映射规则  设备编号
                                execWorkerPool.execute(new GnssRTCMDataTransferWorker(deviceId, frameData));
                            }
                        } else {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        CacheData data = conditionCacheManager.get();
                        if(data != null){
                            ByteBuf buf = Unpooled.wrappedBuffer(data.getData());
                            log.info("[GnssConditionTransfer] deviceId:{} , 工况数据：{}",data.getDeviceId(), buf.toString(CharsetUtil.UTF_8));
                            gnssConditionTransferWorker.send(String.valueOf(data.getDeviceId()), buf.toString(CharsetUtil.UTF_8));
                        } else {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public static void main(String[] args) {
//        byte[] frameData = {(byte)0xd3,(byte)0x00,(byte)0x13,(byte)0x3E,(byte)0xD7,(byte)0xD3,(byte)0x02,(byte)0x02,(byte)0x98,
//                (byte)0x0E,(byte)0xDE,(byte)0xEF,(byte)0x34,(byte)0xB4,(byte)0xBD,(byte)0x62,(byte)0xAC,(byte)0x09,(byte)0x41,
//                (byte)0x98,(byte)0x6F,(byte)0x33,(byte)0x36,(byte)0x0B,(byte)0x98};
//        byte[] frameData = {(byte)0xd3,(byte)0x00,(byte)0x40,(byte)0x41};
//        System.out.println(BitUtils.bitToInt(frameData, 14, 10) );
//        // 计算校验和
//        int targetCRC = BitUtils.bitToInt(frameData, (frameData.length - CRCBYTELENGTH) * 8, CRCBYTELENGTH * 8);
//        int calcCrc = calcCrc(frameData);
//        System.out.println(targetCRC);
//        System.out.println(calcCrc);
    }

}
